///| 人脸检测和关键点预测模块
/// 使用 dlib 进行人脸检测和81点关键点预测

import python
from utils import { Point, Rectangle, FaceDetectionError, Result }

/// 人脸检测器
pub struct FaceDetector {
  detector : python.PyObject
  predictor : python.PyObject
}

/// 人脸检测结果
pub struct Face {
  pub bounds : Rectangle
  pub landmarks : Array[Point]
}

/// 初始化人脸检测器
pub fn FaceDetector::new(model_path : String) -> Result[FaceDetector] {
  try {
    let dlib = python.import("dlib")
    let detector = dlib.get_frontal_face_detector()
    let predictor = dlib.shape_predictor(model_path)
    
    Ok({ detector, predictor })
  } catch e {
    Err(ModelError("Failed to initialize face detector: " + e.to_string()))
  }
}

/// 检测人脸并预测关键点
pub fn FaceDetector::detect_faces(self : FaceDetector, image : python.PyObject) -> Result[Array[Face]] {
  try {
    let cv2 = python.import("cv2")
    let np = python.import("numpy")
    
    // 转换为灰度图像
    let gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
    
    // 检测人脸
    let faces = self.detector(gray)
    let mut result : Array[Face] = []
    
    // 对每个检测到的人脸预测关键点
    for face in faces {
      let landmarks = self.predictor(gray, face)
      let mut points : Array[Point] = []
      
      // 提取81个关键点
      for i in 0..<81 {
        let point = landmarks.part(i)
        points.push(Point::new(point.x, point.y))
      }
      
      let face_rect = Rectangle::new(
        face.left(),
        face.top(),
        face.width(),
        face.height()
      )
      
      result.push({ bounds: face_rect, landmarks: points })
    }
    
    Ok(result)
  } catch e {
    Err(ProcessingError("Face detection failed: " + e.to_string()))
  }
}

/// 在图像上绘制关键点
pub fn draw_landmarks(image : python.PyObject, faces : Array[Face]) -> Result[python.PyObject] {
  try {
    let cv2 = python.import("cv2")
    let mut result_image = image.copy()
    
    for face in faces {
      for point in face.landmarks {
        cv2.circle(result_image, (point.x, point.y), 2, (0, 255, 0), -1)
      }
    }
    
    Ok(result_image)
  } catch e {
    Err(ProcessingError("Failed to draw landmarks: " + e.to_string()))
  }
}